﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using FluentPS.Extensions;
using FluentPS.WebSvcLookupTable;

namespace FluentPS.Services.Impl
{
    public class LookupTableService : ILookupTableService
    {
        internal const string WebServiceUrl = "LookupTable.asmx";
        private const int DefaultLangId = 0;

        private readonly ISessionService _sessionService;
        private readonly LookupTable _wssLookupTable;
        private readonly ILogService _logService;

        public LookupTableService(ISessionService sessionService, ILogService logService)
        {
            _sessionService = sessionService;
            _logService = logService;
            _wssLookupTable = new LookupTable();
            Init();
        }

        public void Init()
        {
            _wssLookupTable.Url = _sessionService.PsiBaseUrl + WebServiceUrl;
            _wssLookupTable.UseDefaultCredentials = true;
        }

        #region ILookupTableService Members

        public object GetLookupTableValue(Guid lookupTableUid, Guid ltStructUid, Type valueType)
        {
            try
            {
                using (LookupTableDataSet dsLookupTables = _wssLookupTable.ReadLookupTablesByUids(
                    new[] { lookupTableUid },
                    false,
                    DefaultLangId))
                {
                    dsLookupTables.LookupTableTrees.Rows
                        .Cast<LookupTableDataSet.LookupTableTreesRow>()
                        .Where(row => row.LT_UID == lookupTableUid && row.LT_STRUCT_UID == ltStructUid)
                        .Select(row => GetDataFromLookupTableValueRow(row, valueType))
                        .ToList()
                        .FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                _logService.Log(string.Format("Unable to read lookup table {0}. Exception: {1}", lookupTableUid, ex.Message));
            }
            return null;
        }

        public IList GetLookupTableValues(Guid lookupTableUid, IList<Guid> ltStructUids, Type valueType)
        {
            IList items = valueType.CreateGenericList();
            try
            {
                using (LookupTableDataSet dsLookupTables = _wssLookupTable.ReadLookupTablesByUids(
                    new[] {lookupTableUid},
                    false,
                    DefaultLangId))
                {
                    dsLookupTables.LookupTableTrees.Rows
                        .Cast<LookupTableDataSet.LookupTableTreesRow>()
                        .Where(row=>row.LT_UID == lookupTableUid && ltStructUids.Contains(row.LT_STRUCT_UID))
                        .ToList()
                        .ForEach(row => items.Add(GetDataFromLookupTableValueRow(row, valueType)));
                }
            }
            catch (Exception ex)
            {
                _logService.Log(string.Format("Unable to read lookup table {0}. Exception: {1}", lookupTableUid, ex.Message));
            }
            return items;
        }

        #endregion

        private static object GetDataFromLookupTableValueRow(LookupTableDataSet.LookupTableTreesRow row, Type dataType)
        {
            if (typeof(string).Equals(dataType))
                return row.LT_VALUE_TEXT;
            if (typeof(decimal).Equals(dataType))
                return row.LT_VALUE_NUM;
            if (typeof(int).Equals(dataType))
                return (int)row.LT_VALUE_NUM;
            if (typeof(DateTime).Equals(dataType))
                return row.LT_VALUE_DATE;

            return null;
        }

    }
}
